﻿using Microsoft.Lync.Model;
using Microsoft.Lync.Model.Group;
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;

namespace WPFDemo
{
    /// <summary>
    /// addCustomGroup.xaml の相互作用ロジック
    /// </summary>
    public partial class addCustomGroup : Window
    {
        #region "グローバル変数"
        LyncClient LyncClient;
        ContactManager ContactManager;

        public ObservableCollection<GroupInfo> Groups { get; set; }
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region "フォームロード"
        public addCustomGroup()
        {
            InitializeComponent();
        }

        private void Window_Loaded_1(object sender, RoutedEventArgs e)
        {
            CustomGroupNameTextBox.Focus();
            try
            {
                Groups = new ObservableCollection<GroupInfo>();
                LyncClient = LyncClient.GetClient();
                ContactManager = LyncClient.ContactManager;
                ContactManager.GroupAdded += new EventHandler<GroupCollectionChangedEventArgs>(ContactManager_GroupAdded);
                ContactManager.GroupRemoved += new EventHandler<GroupCollectionChangedEventArgs>(ContactManager_GroupRemoved);
                this.DataContext = this;
                PopulateGroupInfo();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        #endregion

        #region "プライベート機能"
        /// <summary>
        /// コンタクトマネージャーからカスタムグループを削除機能
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">GroupCollectionChangedEventArgs</param>
        void ContactManager_GroupRemoved(object sender, GroupCollectionChangedEventArgs e)
        {
            UpdateGroupList();
        }

        /// <summary>
        /// コンタクトマネージャーにカスタムグループを追加機能
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">GroupCollectionChangedEventArgs</param>
        void ContactManager_GroupAdded(object sender, GroupCollectionChangedEventArgs e)
        {
            UpdateGroupList();
        }

        /// <summary>
        /// グループ情報を取得
        /// </summary>
        /// <param name=""></param>
        private void UpdateGroupList()
        {
            this.Dispatcher.Invoke(new Action(() =>
            {
                PopulateGroupInfo();
                if (groupListBox.Items.Count > 0)
                {
                    groupListBox.SelectedIndex = 0;
                }
            }), null);
        }

        /// <summary>
        /// グループ情報を取得
        /// </summary>
        /// <param name=""></param>
        private void PopulateGroupInfo()
        {
            Groups.Clear();

            Group favoriteGroup = GetSpecialGroup(GroupType.FavoriteContacts);
            Groups.Add(GetGroupInfo(favoriteGroup));
            Group frequentGroup = GetSpecialGroup(GroupType.FrequentContacts);
            Groups.Add(GetGroupInfo(frequentGroup));
            Group otherContactsGroup = GetOtherContactsGroup();
            Groups.Add(GetGroupInfo(otherContactsGroup));

            foreach (Group group in ContactManager.Groups)
            {
                if (group.Type == GroupType.CustomGroup && group.Name != "Other Contacts")
                {
                    Groups.Add(GetGroupInfo(group));
                }
            }

            foreach (Group group in ContactManager.Groups)
            {
                if (group.Type == GroupType.DistributionGroup)
                {
                    Groups.Add(GetGroupInfo(group));
                }
            }

            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("Groups"));
            }
        }

        /// <summary>
        /// Other Contactグループ情報を取得
        /// </summary>
        /// <param name=""></param>
        private Group GetOtherContactsGroup()
        {
            foreach (Group group in ContactManager.Groups)
            {
                if (group.Type == GroupType.CustomGroup && group.Name == "Other Contacts")
                {
                    return group;
                }
            }
            return null;            
        }

        /// <summary>
        /// Other Contactグループ情報を取得
        /// </summary>
        /// <param name=""></param>
        private Group GetSpecialGroup(GroupType groupType)
        {
            foreach (Group group in ContactManager.Groups)
            {
                if (group.Type == groupType)
                {
                    return group;
                }
            }
            return null;
        }

        /// <summary>
        /// お気に入りグループと最も利用される連絡先グループ情報を取得
        /// </summary>
        /// <param name=""></param>
        private GroupInfo GetGroupInfo(Group group)
        {
            int ContactCounts = 0;

            if (group != null)
            {
                GroupType type = group.Type;

                if (type != GroupType.DistributionGroup)
                {
                    ContactCounts = group.Count;
                }
            }
            return new GroupInfo(group);
        }

        /// <summary>
        /// カスタムグループ追加機能
        /// </summary>
        /// <param name="ar">IAsyncResult</param>
        private void AddGroup_Callback(IAsyncResult ar)
        {
            try
            {
                ContactManager.EndAddGroup(ar);
            }
            catch (Exception ex)
            {
                MessageBox.Show(
                            "グループを追加する時に、エラーが発生しました。" + ex.Message,
                            "カスタムグループ追加エラー",
                            MessageBoxButton.OK,
                            MessageBoxImage.Information);
                return;
            }
        }

        /// <summary>
        /// カスタムグループ削除機能
        /// </summary>
        /// <param name="ar">IAsyncResult</param>
        private void RemoveGroup_Callback(IAsyncResult ar)
        {
            try
            {
                ContactManager.EndRemoveGroup(ar);
                this.Dispatcher.Invoke(new Action(() =>
                {
                    PopulateGroupInfo();
                    if (groupListBox.Items.Count > 0)
                    {
                        groupListBox.SelectedIndex = 0;
                    }
                }), null);
            }
            catch (Exception ex)
            {
                MessageBox.Show(
                           "グループを削除する時に、エラーが発生しました。" + ex.Message,
                           "カスタムグループ削除エラー",
                           MessageBoxButton.OK,
                           MessageBoxImage.Information);
                return;
            }
        }
        #endregion

        #region "ボタンイベント"
        /// <summary>
        /// カスタムグループ追加ボタンイベント
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">RoutedEventArgs</param>
        private void AddCustomGroupButton_Click(object sender, RoutedEventArgs e)
        {
            string groupName = CustomGroupNameTextBox.Text.Trim();
            if (!String.IsNullOrWhiteSpace(groupName))
            {
                foreach (GroupInfo gi in Groups)
                {
                    if (gi.GroupName.Equals(groupName, StringComparison.InvariantCultureIgnoreCase))
                    {
                        MessageBox.Show(
                            string.Format("グループ \"{0}\" は重複しています. 追加できません.", groupName),
                            "カスタムグループ追加エラー",
                            MessageBoxButton.OK,
                            MessageBoxImage.Exclamation);
                        return;
                    }
                }
                try
                {
                    ContactManager.BeginAddGroup(CustomGroupNameTextBox.Text.Trim(), AddGroup_Callback, null);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(
                           "グループを追加する時に、エラーが発生しました。" + ex.Message,
                           "カスタムグループ追加エラー",
                           MessageBoxButton.OK,
                           MessageBoxImage.Information);
                    return;
                }
            }
            else
            {
                CustomGroupNameTextBox.Focus();
                MessageBox.Show(
                            string.Format("グループ名を入力してください."),
                            "カスタムグループ追加エラー",
                            MessageBoxButton.OK,
                            MessageBoxImage.Exclamation);
                return;
            }
        }

        /// <summary>
        /// カスタムグループ削除ボタンイベント
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">RoutedEventArgs</param>
        private void RemoveCustomGroupButton_Click(object sender, RoutedEventArgs e)
        {
            GroupInfo groupInfo = (GroupInfo)groupListBox.SelectedItem;
            if (groupInfo != null)
            {
                MessageBoxResult mbr = MessageBox.Show(
                    string.Format("\"{0}\"グループを削除しますか?", groupInfo.GroupName),
                    "グループ削除確認",
                    MessageBoxButton.YesNo,
                    MessageBoxImage.Warning);
                if (mbr == MessageBoxResult.Yes)
                {
                    try
                    {
                        Group group = groupInfo.Group;
                        ContactManager.BeginRemoveGroup(group, RemoveGroup_Callback, null);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(
                           "グループを削除する時に、エラーが発生しました。" + ex.Message,
                           "カスタムグループ削除エラー",
                           MessageBoxButton.OK,
                           MessageBoxImage.Information);
                        return;
                    }
                }
            }
            else
            {
                CustomGroupNameTextBox.Focus();
                MessageBox.Show(
                            string.Format("削除するグループを選択してください."),
                            "カスタムグループ削除エラー",
                            MessageBoxButton.OK,
                            MessageBoxImage.Exclamation);
                return;
            }
        }
        #endregion 

        #region "リストボックスイベント"
        /// <summary>
        /// グループリストボックス選択変更イベント
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">SelectionChangedEventArgs</param>
        private void groupListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (groupListBox.SelectedItem != null)
            {
                bool canRemove = ((GroupInfo)groupListBox.SelectedItem).CanRemove;
                RemoveCustomGroupButton.IsEnabled = canRemove;

                CustomGroupNameTextBox.Text = ((GroupInfo)groupListBox.SelectedItem).GroupName;
            }
        }
        #endregion
    }

    /// <summary>
    /// グループ情報取得クラス 
    /// </summary>
    /// <param name=""></param>
    public class GroupInfo
    {
        #region "Get、Set"
        public string GroupName { get; set; }
        public int ContactNumber { get; set; }
        public GroupType Type { get; set; }
        public bool CanRemove { get; set; }

        public Group Group { get; set; }
        #endregion

        #region "グループ情報取得機能"
        public GroupInfo(Group group)
        {
            this.Group = group;
            if (group != null)
            {
                this.GroupName = group.Name;
                this.ContactNumber = group.Count;
                this.Type = group.Type;
                if (group.Type == GroupType.DistributionGroup ||
                    (group.Type == GroupType.CustomGroup && group.Name != "Other Contacts"))
                {
                    this.CanRemove = true;
                }
                else
                {
                    this.CanRemove = false;
                }
            }
        }
        #endregion
    }
}
